對應《30天挑戰精通 PowerShell》一書的第 12 章
今天來深入探討如何在 PowerShell 中進行篩選和比較,使其能更有效地處理資料。透過理解篩選技巧和比較運算子的使用,將能夠從大量的資訊中快速擷取出有用的內容,提升工作效率。
在處理大量資料時,取得過多的資訊可能會讓人不知所措。PowerShell 提供了兩種通用的模型來精簡結果,兩種方法都稱為篩選( filtering )。
透過 cmdlet 本身提供的 Parameter 去篩選出你指定的內容,舉例,當我們執行 Get-ChildItem 時,可以透過 -Name 去 filter 出包含檔案名稱包含 txt 字眼,換句話說,嘗試指示「擷取資訊的 cmdlet 」只擷取「你指定的內容」。
# Gets the items and child items in one or more specified locations.
PS /Users/kanglin/code/30days> Get-ChildItem
Directory: /Users/kanglin/code/30days
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
-rw-r--r-- kanglin staff 2024/9/24 22:14 63 aliases.txt
-rw-r--r-- kanglin staff 2024/9/24 13:09 90 modules.txt
-rw-r--r-- kanglin staff 2024/9/26 10:43 29233 result.json
-rw-r--r-- kanglin staff 2024/9/26 10:47 2943 Untitled.ipynb
PS /Users/kanglin/code/30days> Get-ChildItem -Name *.txt
aliases.txt
modules.txt
透過 pipeline,迭代式的先接收第一組 cmdlet 提供的內容後,再使用第二組 cmdlet( Where-Object )在管線中篩選物件。
# 列出系統中使用 CPU 時間超過一定值的 Process。
PS /Users/kanglin/code/30days> Get-Process | Where-Object { $_.CPU -gt 100 }
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
0 0.00 75.03 517.71 24419 1 Anytype
0 0.00 30.06 349.13 24420 1 Anytype Helper
0 0.00 131.83 1,582.31 24423 1 Anytype Helper
0 0.00 92.77 749.49 24422 1 anytypeHelper
0 0.00 15.08 272.49 24106 1 AXVisualSupport
0 0.00 125.48 764.37 24428 1 ChatGPT
0 0.00 14.84 377.43 25076 1 Code Helper (GP
0 0.00 26.41 138.41 24088 1 ControlCenter
0 0.00 21.20 324.91 24096 1 corespeechd
0 0.00 22.70 105.63 24394 1 CursorUIViewSer
0 0.00 29.98 162.85 41705 1 Easydict
0 0.00 38.78 181.01 25070 1 Electron
0 0.00 10.38 107.72 24138 1 fileproviderd
0 0.00 42.23 176.45 24102 1 Finder
0 0.00 155.28 1,614.23 24576 1 Google Chrome
Where-Object
用於篩選物件。$_.
代表管線中當前的物件。-eq
是比較運算子,表示「等於」。將篩選條件儘早應用,能夠提升命令的執行效率。這被稱為「篩選左移」,意思是在管線的左側盡可能地進行篩選。
篩選左移這個技術的缺點在於,每個 cmdlet 都可以實作自己的特定篩選方式,而且每個 cmdlet 在執行篩選的能力亦有所差異。
然後當無法透過單一 cmdlet 本身所提供的第一種 Filter 方式時,我們轉而使用第二種方式,透過 Where-Object
來篩選,而這個篩選的過程則需要用到比較運算式( comparison operator )。
在電腦領域中,「比較」就是要把兩個物件或值拿來判斷彼此之間的關係。
透過使用「比較運算子」來指明你想要判斷的關係種類。在簡單的判斷中,結果會是一個布林值( Boolean value ):True 或 False。換言之,判斷出來的關係要嘛是你所指定的那樣,要嘛不是。
PowerShell 提供了一系列的比較運算子,用於比較數值、字串和模式。
-eq
:等於-ne
:不等於-gt
:大於-lt
:小於-like
:匹配字串模式(支援萬用字元)-match
:正則表達式匹配而想要一次比較多項條件時,可使用邏輯運算子( logical operator )
-and
:邏輯「和」。只有當兩個子運算式都為** True** 時,結果才為** True**。(5 -gt 10) -and (10 -qt 100)
# 第一個子運算式:5 -gt 10,即 5 是否大於 10,結果為 False。
# 第二個子運算式:10 -lt 100,即 10 是否小於 100,結果為 True。
# 整體運算式:False -and True,因為 -and 需要兩個子運算式都為 True,所以結果為 False。
-or
:邏輯「或」。只要有一個子運算式為** True**,結果就為** True**。(5 -gt 10) -or (10 -lt 100)
# 第一個子運算式:5 -gt 10,結果為 False。
# 第二個子運算式:10 -lt 100,結果為 True。
# 整體運算式:False -or True,因為 -or 只要有一個子運算式為 True,結果就為 True。
-not
:邏輯「非」。將布林值取反**,True** 變** False,False** 變** True**。如果您想要列出所有 不 以 “Win” 開頭的服務:
Get-Service | Where-Object { -not ($_.Name -like 'Win*') }
在使用 PowerShell 進行篩選和比較時,可能會遇到一些常見的困惑點。
為什麼要優先在左側進行篩選?
不優化的篩選
Get-Service | Where-Object { $_.Status -eq 'Stopped' }
優化的篩選
Get-Service -Status Stopped
Day 14 - 遠端控制:一對一及一對多